﻿using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Drawing;

namespace Resource.Controls
{
    public enum WinControlModes
    {
        Normal,
        DGSelf,
        DGOther
    }


    /// <summary>
    /// 带句柄的控件
    /// </summary>
    public class WinControl : HwndHost
    {
        #region 依赖属性

        #region 窗口句柄

        public static readonly DependencyProperty WinHwndProperty =
            DependencyProperty.Register(
                "WinHwnd",
                typeof(IntPtr),
                typeof(WinControl),
                new PropertyMetadata(new IntPtr(-1)));

        public IntPtr WinHwnd
        {
            get { return (IntPtr)GetValue(WinHwndProperty); }
            set { SetValue(WinHwndProperty, value); }
        }

        #endregion

        #region 窗口类型

        public static readonly DependencyProperty WinModeProperty =
            DependencyProperty.Register(
                "WinMode",
                typeof(WinControlModes),
                typeof(WinControl),
                new PropertyMetadata(WinControlModes.Normal, WinModePropertyChanged));

        public WinControlModes WinMode
        {
            get { return (WinControlModes)GetValue(WinModeProperty); }
            set { SetValue(WinModeProperty, value); }
        }

        private static void WinModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            WinControl control = d as WinControl;
            control?.WinModePropertyChanged();
        }

        #endregion
        #endregion

        #region 方法
        /// <summary>
        /// 生成窗口
        /// </summary>
        /// <param name="hwndParent"></param>
        /// <returns></returns>
        protected override HandleRef BuildWindowCore(HandleRef hwndParent)
        {
            //TestColor();
            uint hwnd = WinAPI.CreateWindowEx(0,
                                                "static",
                                                string.Empty,
                                                (uint)WindowStyles.WS_CHILD,
                                                0,
                                                0,
                                                (int)ActualWidth,
                                                (int)ActualHeight,
                                                (uint)hwndParent.Handle,
                                                0,
                                                0,
                                                0);

            WinAPI.SetWindowPos(hwnd, WindowPos.HWND_Top, 0, 0, 0, 0, PosFlags.SWP_NOMOVE);

            IntPtr handle = (IntPtr)hwnd;
            if (!Equals(WinHwnd, handle))
                WinHwnd = handle;

            WinModePropertyChanged();

            return new HandleRef(this, handle);
        }

        /// <summary>
        /// 释放窗口
        /// </summary>
        /// <param name="hwnd"></param>
        protected override void DestroyWindowCore(HandleRef hwnd)
        {
            if (WinHwnd == IntPtr.Zero)
                return;
            WinAPI.DestroyWindow((uint)WinHwnd);
            WinHwnd = IntPtr.Zero;
        }

        /// <summary>
        /// 窗口类型改变
        /// </summary>
        private void WinModePropertyChanged()
        {
            if ((int)WinHwnd < 0)
                return;
            switch (WinMode)
            {
                case WinControlModes.Normal:
                    WinAPI.SetWindowLong(WinHwnd, (int)WindowLongFlags.GWL_STYLE,
                        (int)WindowStyles.WS_CHILD |
                        (int)WindowOtherStyles.SS_BLACKRECT);
                    break;
                case WinControlModes.DGSelf:
                    WinAPI.SetWindowLong(WinHwnd, (int)WindowLongFlags.GWL_STYLE,
                        (int)WindowStyles.WS_CHILD |
                        (int)WindowOtherStyles.SS_BITMAP |
                        (int)WindowStyles.WS_CLIPSIBLINGS |
                       (int)WindowStyles.WS_CLIPCHILDREN);
                    break;
                case WinControlModes.DGOther:
                    WinAPI.SetWindowLong(WinHwnd, (int)WindowLongFlags.GWL_STYLE,
                        (int)WindowStyles.WS_CHILD |
                        (int)WindowOtherStyles.SS_BITMAP);
                    break;
            }
            SetColor();
        }

        private void SetColor()
        {
            uint oldColor = WinAPI.GetSysColor((int)ColorTypes.COLOR_3DDKSHADOW);
            Color sampleColor = Color.Black;
            int newColor = ColorTranslator.ToWin32(sampleColor);

            if (oldColor != newColor)
            {
                int[] elements = { (int)ColorTypes.COLOR_3DDKSHADOW };
                int[] colors = { newColor };
                WinAPI.SetSysColors(elements.Length, elements, colors);
            }
        }

        #endregion
    }
}